﻿using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Web;

namespace MOKA.TPM.Utility
{
    public static class HttpHelper
    {
        public static string ConvertToUrlParams(Dictionary<string, object> parameters)
        {
            var query = HttpUtility.ParseQueryString(string.Empty);

            foreach (var kvp in parameters)
            {
                query[kvp.Key] = kvp.Value.ToString();
            }

            return query.ToString();
        }

        /// <summary>
        /// 生成SM2加密字符串
        /// </summary>
        /// <param name="pubKey"></param>
        /// <param name="srcData"></param>
        /// <returns></returns>
        public static string EncryptPublic(String pubKey, string data_string)
        {
            // 如果是130位公钥，.NET使用的话，把开头的04截取掉
            if (pubKey.Length == 130)
            {
                pubKey = pubKey.Substring(2, 128);
            }
            // 公钥X，前64位
            string x = pubKey.Substring(0, 64);
            // 公钥Y，后64位
            string y = pubKey.Substring(64);
            // 获取公钥对象
            AsymmetricKeyParameter publicKey1 = GM.GetPublickeyFromXY(new BigInteger(x, 16), new BigInteger(y, 16));
            // Sm2Encrypt: C1C3C2
            // Sm2EncryptOld: C1C2C3
            byte[] digestByte = GM.Sm2Encrypt(Encoding.UTF8.GetBytes(data_string), publicKey1);
            return Hex.ToHexString(digestByte);
        }

        /// <summary>
        /// 解密 JWT token 的信息
        /// </summary>
        /// <param name="token">JWT token 字符串</param>
        /// <returns>解密后的对象</returns>
        public static dynamic DecryptJWT(string token)
        {
            // 替换字符以符合 Base64 标准
            token = token.Replace('_', '/').Replace('-', '+');

            // 分割 JWT 并解码 payload 部分
            string[] parts = token.Split('.');
            if (parts.Length != 3)
            {
                throw new ArgumentException("Invalid JWT token format.");
            }

            string payload = parts[1];
            // Base64 解码
            byte[] jsonBytes = Convert.FromBase64String(PadBase64String(payload));
            string json = Encoding.UTF8.GetString(jsonBytes);

            // 解析 JSON
            return JsonConvert.DeserializeObject<dynamic>(json);
        }

        /// <summary>
        /// 将 JWT 时间戳转换成 Date
        /// </summary>
        /// <param name="timestamp">时间戳</param>
        /// <returns>DateTime 对象</returns>
        public static DateTime GetJWTDate(long timestamp)
        {
            // Unix 时间戳起始时间
            DateTimeOffset unixEpoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
            // 将时间戳转换为 DateTime
            return unixEpoch.AddSeconds(timestamp).UtcDateTime;
        }

        /// <summary>
        /// 为 Base64 字符串添加必要的填充
        /// </summary>
        /// <param name="base64">Base64 字符串</param>
        /// <returns>填充后的 Base64 字符串</returns>
        private static string PadBase64String(string base64)
        {
            switch (base64.Length % 4)
            {
                case 2: return base64 + "==";
                case 3: return base64 + "=";
                default: return base64;
            }
        }

        /// <summary>
        /// 如果有大小写问题，序列化用这个
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string Object2JsonString(object obj)
        {
            if (obj == null)
                return "";
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings()
            {
                ContractResolver = (IContractResolver)new CamelCasePropertyNamesContractResolver()
            });
        }

        public static TObj JsonString2Object<TObj>(string str)
        {
            return JsonConvert.DeserializeObject<TObj>(str, new JsonSerializerSettings()
            {
                ContractResolver = (IContractResolver)new CamelCasePropertyNamesContractResolver()
            });
        }
    }
}